# -*- encoding: utf-8 -*-
##############################################################################
#
#
##############################################################################

from datetime import datetime
from odoo.tools import float_compare
from odoo.exceptions import except_orm, Warning, RedirectWarning
import odoo.addons.decimal_precision as dp
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError


class sale_mrp_prepare(models.Model):
    _name = 'sale.mrp.prepare'
    _order = 'name desc'

    name = fields.Many2one('sale.order.line', u'说明', required=True)
    picking_type_id = fields.Many2one('stock.picking.type', u'作业', domain=[('code', '=', 'mrp_operation')])
    sale_order_id = fields.Many2one('sale.order', u'销售订单')
    plan_id = fields.Many2one('sale.mrp.plan', u'计划单')
    user_id = fields.Many2one('res.users', u'用户', default=lambda self: self.env.user)
    partner_id = fields.Many2one('res.partner', u'业务伙伴')
    production_id = fields.Many2one('mrp.production', u'生产单')
    product_id = fields.Many2one('product.product', u'产品', domain=[('purchase_ok', '=', True)], change_default=True,
                                 required=True)
    product_qty = fields.Float(u'数量', digits_compute=dp.get_precision('Product Unit of Measure'), required=True,
                               default=1)
    need_date = fields.Datetime(u'订购日期', required=True, select=True)
    ask_for_date = fields.Datetime(u'要求日期', select=True)
    mrp_reply_date = fields.Datetime(u'生管回复日期', select=True)

    priority = fields.Selection([('0', u'暂缓'), ('1', u'一般'), ('2', u'紧急'), ('3', u'非常紧急')], u'优先级',
                                default='1')
    date_planned = fields.Date(u'计划时间', select=True)
    start_date = fields.Date(u'转计划时间', select=True, default='2099-12-31')
    product_uom = fields.Many2one('product.uom', u'单位', required=True,
                                  default=lambda self: self.env.ref('product.product_uom_unit'))
    # product_bom = fields.Many2one('mrp.bom', u'清单', domain="[('product_tmpl_id.product_variant_ids','=',product_id)]")
    product_bom = fields.Many2one('mrp.bom', u'清单', domain="[('product_id','=',product_id)]")
    # < field
    # name = "bom_id"
    # domain = "['&amp;', '|',('product_id','=',product_id),'&amp;',('product_tmpl_id.product_variant_ids','=',product_id),                                                 ('product_id','=',False),                                                 ('type', '=', 'normal')]"
    # context = "{'default_product_tmpl_id': product_tmpl_id}"
    # required = "1"
    # attrs = "{'readonly': [('has_moves', '=', True)]}" / >

    mrp_plan_id = fields.Many2one('sale.mrp.plan', u'生产计划')
    mrp_plan_order_id = fields.Many2one('sale.mrp.plan.order', related="mrp_plan_id.order_id", string=u'计划单',
                                        readonly=True)
    state = fields.Selection([
        ('draft', u'草稿'),
        ('cancel', u'取消'),
        ('waiting', u'审核'),
        ('done', u'已转计划'),
    ], u'状态', readonly=True, default='draft')
    note = fields.Text(u'申请备注')

    @api.onchange('product_id')
    def onchange_product_id(self):
        if self.product_id:
            self.product_uom = self.product_id.uom_id.id


class sale_mrp_plan_order(models.Model):
    _name = 'sale.mrp.plan.order'
    _order = 'name desc'

    name = fields.Char(u'单号', required=True, default='New')
    origin = fields.Char(u'来源')
    date = fields.Date(u'创建日期', select=True, default=fields.datetime.now())
    confirm_date = fields.Date(u'审核日期', select=True)
    start_date = fields.Date(u'转生产时间', select=True)
    user_id = fields.Many2one('res.users', u'生管', default=lambda self: self.env.user)
    department_id = fields.Many2one('hr.department', u'部门',
                                    default=lambda self: self.env.user.employee_ids[0].department_id.id)
    sale_mrp_plans = fields.One2many('sale.mrp.plan', 'order_id', u'计划明细')
    state = fields.Selection([
        ('draft', u'草稿'),
        ('confirm', u'确认'),
        ('waiting', u'待转'),
        ('done', u'已转生产'),
        ('cancel', u'取消'),
    ], u'状态', readonly=True, default='draft')

    @api.model
    def create(self, values):
        if not values.get('name', False) or values['name'] == _('New'):
            values['name'] = self.env['ir.sequence'].next_by_code('sale.mrp.plan.order') or _('New')
        return super(sale_mrp_plan_order, self).create(values)

    @api.multi
    def per_order_confirm(self):
        for line in self.sale_mrp_plans:
            line.per_order_confirm()
        self.write({'state': 'confirm'})
        return True

    @api.multi
    def per_order_cancel(self):
        for line in self.sale_mrp_plans:
            if line.state == 'done':
                raise ValidationError(u'已有明细转生产,不允许取消!')
            line.per_order_cancel()
        self.write({'state': 'cancel'})
        return True

    @api.multi
    def per_order_waiting(self):
        for line in self.sale_mrp_plans:
            line.per_order_waiting()
        self.write({
            'confirm_date': fields.datetime.now(),
            'state': 'waiting',
        })
        return True

    @api.multi
    def per_order_done(self):
        # 创建生产单
        for line in self.sale_mrp_plans:
            if line.state == 'done':
                continue
            line.per_order_done()
        self.write({'state': 'done',
                    'start_date': fields.datetime.now()
                    })
        return True

    @api.multi
    def per_order_draft(self):
        for line in self.sale_mrp_plans:
            if line.state == 'done':
                raise ValidationError(u'已有明细转生产,不允许重置!')
            line.per_order_draft()
        self.write({
            'confirm_date': None,
            'state': 'draft',
        })
        return True


class sale_mrp_plan(models.Model):
    _name = 'sale.mrp.plan'
    _order = 'order_id desc'

    name = fields.Char(u'单号', required=True, default='New')
    # sale_order_line_id = fields.Many2one('sale.order.line', u'说明', required=True)
    track_number = fields.Char(u"追踪号", states={
        'draft': [('readonly', False)],
    }, readonly=True)
    order_id = fields.Many2one('sale.mrp.plan.order', u'计划单')
    so_lines = fields.One2many('sale.order.line', 'plan_id', u'销售明细')
    picking_type_id = fields.Many2one('stock.picking.type', u'作业', domain=[('code', '=', 'mrp_operation')])
    user_id = fields.Many2one('res.users', u'用户', default=lambda self: self.env.user)
    partner_id = fields.Many2one('res.partner', u'业务伙伴')
    production_id = fields.Many2one('mrp.production', u'生产单')
    product_id = fields.Many2one('product.product', u'产品', domain=[('type', 'in', ['product', 'consu'])],
                                 change_default=True, required=True)
    product_qty = fields.Float(u'数量', digits_compute=dp.get_precision('Product Unit of Measure'), required=True,
                               default=1)
    need_date = fields.Date(u'需求日期', required=True, select=True)
    priority = fields.Selection([('0', u'暂缓'), ('1', u'一般'), ('2', u'紧急'), ('3', u'非常紧急')], u'优先级',
                                default='1')
    date_planned_start = fields.Date(u'计划开始', select=True)
    date_planned_end = fields.Date(u'计划结束', select=True)
    start_date = fields.Date(u'转生产时间', select=True)
    confirm_date = fields.Date(u'审核日期', select=True)
    product_uom = fields.Many2one('product.uom', u'单位', required=True,
                                  default=lambda self: self.env.ref('product.product_uom_unit'))
    # product_bom = fields.Many2one('mrp.bom', u'清单', domain="[('product_tmpl_id.product_variant_ids','=',product_id)]")
    product_bom = fields.Many2one('mrp.bom', u'清单', domain="[('product_id','=',product_id)]")
    state = fields.Selection([
        ('draft', u'草稿'),
        ('confirm', u'确认'),
        ('waiting', u'待转'),
        ('done', u'已转生产'),
        ('cancel', u'取消'),
    ], u'状态', readonly=True, default='draft')
    note = fields.Text(u'申请备注')

    @api.model
    def create(self, values):
        if not values.get('name', False) or values['name'] == _('New'):
            values['name'] = self.env['ir.sequence'].next_by_code('sale.mrp.plan') or _('New')
        return super(sale_mrp_plan, self).create(values)

    @api.onchange('product_id')
    def onchange_product_id(self):
        if self.product_id:
            self.product_uom = self.product_id.uom_id.id

    @api.onchange('product_bom')
    def onchange_product_bom(self):
        if self.product_bom:
            self.picking_type_id = self.product_bom.picking_type_id.id

    @api.multi
    def per_order_confirm(self):
        self.write({'state': 'confirm'})
        return True

    @api.multi
    def per_order_cancel(self):
        self.write({'state': 'cancel'})
        return True

    @api.multi
    def per_order_waiting(self):
        self.write({
            'confirm_date': fields.datetime.now(),
            'state': 'waiting',
        })
        return True

    @api.multi
    def per_order_done(self):
        # 创建生产单
        if not self.picking_type_id:
            raise ValidationError(u'对不起！必须拥有"作业"字段！')
        if not self.product_uom:
            raise ValidationError(u'对不起！必须拥有"清单"字段！')
        mnf_product_a = self.env['mrp.production'].create({
            'product_id': self.product_id.id,
            'sale_prepare_qty': self.product_qty,
            'product_qty': self.product_qty,
            'product_uom_id': self.product_uom.id,
            'picking_type_id': self.picking_type_id.id,
            'location_src_id': self.picking_type_id.default_location_src_id.id,
            'location_dest_id': self.picking_type_id.default_location_dest_id.id,
            'bom_id': self.product_bom.id,
            'track_number': self.track_number,
            'origin': ",".join(self.so_lines.mapped("order_id.name"))
        })
        if self.date_planned_start:
            mnf_product_a.date_planned_start = self.date_planned_start
        self.write({'state': 'done',
                    'production_id': mnf_product_a.id,
                    'start_date': fields.datetime.now()
                    })
        return True

    @api.multi
    def per_order_draft(self):
        self.write({
            'confirm_date': None,
            'state': 'draft',
        })
        return True
